此方法存在安全问题,已废弃
通道读写检测。类似于socket_select
和stream_select
可以检测channel
是否可进行读写。
function Coroutine\Channel::select(array &$read, array &$write, float $timeout = -1);
当$read
或$write
数组中有部分channel
对象处于可读或可写状态,select
会立即返回,不会产生协程调度。当数组中没有任何channel
可读或可写时,将挂起当前协程,并设置定时器。当其中一个通道可读或可写时,将重新唤醒当前协程。
select
操作只检测channel
列表的可读或可写状态,但并不会读写channel
,在select
调用返回后,可遍历$read
和$write
数组,执行pop
和push
方法,完成通道读写操作。
$read
数组引用类型,元素为channel
对象,读操作检测,可以为null
$write
数组引用类型,元素为channel
对象,写操作检测,可以为null
$timeout
浮点型,超时设置,单位为秒,最小粒度为0.001
秒,即1ms
。默认为0
,表示永不超时。
- 成功返回
true
,底层会修改$read
、$write
数组,$read
和$write
中的元素,即是可读或可写的channel
- 超时或传入的参数错误,如
$read
和$write
中有非channel
对象,底层返回false
早期版本中Coroutine\Channel
由于存在一些问题,在Swoole4.0.3
版本重构并废弃了 Coroutine\Channel::select
方法。所以在Swoole4.0.3
以上的版本请使用channel->pop($timeout)
替代。
$c1 = new chan();
$c2 = new chan();
function fibonacci($c1, $c2)
{
go(function () use ($c1, $c2) {
$a = 0;
$b = 1;
while(1) {
$read_list = [$c2];
$write_list = [$c1];
$result = chan::select($read_list, $write_list, 2);
if ($write_list) {
$t = $a + $b;
$a = $b;
$b = $t;
$c1->push($a);
}
if ($read_list) {
$ret = $c2->pop();
if ($ret === 1) {
return 1;
}
}
}
});
}
$num = 10;
go(function () use ($c1, $c2, $num) {
for ($i = 0; $i < $num; $i ++) {
$ret = $c1->pop();
echo "fibonacci @$i $ret\n";
}
$c2->push(1);
});
fibonacci($c1, $c2);